package frsf.cidisi.exercise.arqueologo.search;


import Interfaz.Index;
import frsf.cidisi.exercise.arqueologo.search.actions.IrAragaey;
import frsf.cidisi.exercise.arqueologo.search.actions.IrAse;
import frsf.cidisi.exercise.arqueologo.search.actions.IrBresol;
import frsf.cidisi.exercise.arqueologo.search.actions.IrBulovoe;
import frsf.cidisi.exercise.arqueologo.search.actions.IrCabe;
import frsf.cidisi.exercise.arqueologo.search.actions.IrCenede;
import frsf.cidisi.exercise.arqueologo.search.actions.IrErgintone;
import frsf.cidisi.exercise.arqueologo.search.actions.IrIcaedur;
import frsf.cidisi.exercise.arqueologo.search.actions.IrMixocu;
import frsf.cidisi.exercise.arqueologo.search.actions.IrPeregaey;
import frsf.cidisi.exercise.arqueologo.search.actions.IrVinizaile;
import frsf.cidisi.exercise.arqueologo.search.actions.RecogerCofre;
import frsf.cidisi.faia.agent.Action;
import frsf.cidisi.faia.agent.Perception;
import frsf.cidisi.faia.agent.search.Problem;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgent;
import frsf.cidisi.faia.solver.search.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ArqueologoAgent extends SearchBasedAgent {

    public ArqueologoAgent(Index r) {

        // The Agent Goal
        ArqueologoGoal agGoal = new ArqueologoGoal();

        // The Agent State
        ArqueologoAgentState agState = new ArqueologoAgentState(r);
        
        this.setAgentState(agState);

        // Create the operators
        Vector<SearchAction> operators = new Vector<SearchAction>();
        operators.addElement(new RecogerCofre());
        operators.addElement(new IrAragaey());
        operators.addElement(new IrErgintone());
        operators.addElement(new IrAse());
        operators.addElement(new IrBresol());
        operators.addElement(new IrBulovoe());
        operators.addElement(new IrCabe());
        operators.addElement(new IrCenede());
        operators.addElement(new IrIcaedur());
        operators.addElement(new IrMixocu());
        operators.addElement(new IrPeregaey());
        operators.addElement(new IrVinizaile());	

        // Create the Problem which the agent will resolve
        Problem problem = new Problem(agGoal, agState, operators);
        this.setProblem(problem);
    }
    /**
     * This method is executed by the simulator to ask the agent for an action.
     */
    @Override
    public Action selectAction() {

        // Create the search strategy
    	/**
         * Para usar una MBCU
         */
    	IStepCostFunction cost = new CostFunction();
    	UniformCostSearch strategy = new UniformCostSearch(cost);
    	/**
         * Para usar una MBH
         */
//    	BreathFirstSearch strategy = new BreathFirstSearch();
    	/**
         * Para usar una MBP
         */
//    	DepthFirstSearch strategy = new DepthFirstSearch();
    	/**
         * Para usar una MBA*
         */
//        IStepCostFunction cost = new CostFunction();
//        IEstimatedCostFunction heuristic = new Heuristic(); 
//    	AStarSearch strategy = new AStarSearch(cost,heuristic);
        
        // Create a Search object with the strategy
        Search searchSolver = new Search(strategy);

        /* Generate an XML file with the search tree. It can also be generated
         * in other formats like PDF with PDF_TREE */
        searchSolver.setVisibleTree(Search.EFAIA_TREE);

        // Set the Search searchSolver.
        this.setSolver(searchSolver);

        // Ask the solver for the best action
        Action selectedAction = null;
        try {
        	selectedAction = this.getSolver().solve(new Object[]{this.getProblem()});
        } catch (Exception ex) {
            Logger.getLogger(ArqueologoAgent.class.getName()).log(Level.SEVERE, null, ex);
        }
        // Return the selected action
        return selectedAction;

    }
    /**
     * This method is executed by the simulator to give the agent a perception.
     * Then it updates its state.
     * @param p
     */
    @Override
    public void see(Perception p) {
        this.getAgentState().updateState(p);
    }
    
    public ArqueologoAgentState getArqueologoAgentState(){
        return (ArqueologoAgentState) this.getAgentState();
    }
}
